package com.weareint.xxljob.dynamic;

import com.weareint.xxljob.XxlJobInfo;
import com.xxl.job.core.biz.model.ReturnT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 *
 *
 * <pre>
 *  XxlJobOperators
 * </pre>
 *
 * @author johnny
 * @date 2021-08-16 11:48 上午
 */
@Slf4j
public class XxlJobOperators {

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;

    @Value("${spring.application.name}")
    private String appname;

    private final RestTemplate restTemplate;

    private static final String ADD_URL = "/jobinfo/addJobInfo";
    //    private static final String UPDATE_URL = "/jobinfo/updateJob";
    private static final String REMOVE_URL = "/jobinfo/removeJobInfo";
    //    private static final String PAUSE_URL = "/jobinfo/pauseJob";
    //    private static final String START_URL = "/jobinfo/startJob";
    //    private static final String ADD_START_URL = "/jobinfo/addAndStart";
    private static final String GET_GROUP_ID = "/jobgroup/getGroupId";
    private static final String SAVE_GROUP = "/jobgroup/save";

    private static final String APP_NAME = "appname";

    public XxlJobOperators(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public void initGroup() {
        Map<String, String> param = new HashMap<>(1);
        param.put(APP_NAME, appname);
        ReturnT<Integer> returnT =
                restTemplate.postForObject(adminAddresses + GET_GROUP_ID, param, ReturnT.class);
        if (returnT == null || returnT.getContent() == null) {
            log.info("【auto create xxlJobGroup :{}】", appname);
            MultiValueMap<String, Object> postParameters = new LinkedMultiValueMap<>();
            postParameters.add("appname", appname);
            postParameters.add("title", appname);
            postParameters.add("addressType", 0);
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "application/x-www-form-urlencoded");
            HttpEntity<MultiValueMap<String, Object>> r = new HttpEntity<>(postParameters, headers);
            returnT = restTemplate.postForObject(adminAddresses + SAVE_GROUP, r, ReturnT.class);
        }
    }

    public void add(XxlJobInfo jobInfo) {
        jobInfo.setAuthor(appname);
        // 查询对应groupId:
        Map<String, String> param = new HashMap<>(1);
        param.put(APP_NAME, appname);

        try { // 查询 groupId
            @SuppressWarnings("unchecked")
            ReturnT<Integer> returnT =
                    restTemplate.postForObject(adminAddresses + GET_GROUP_ID, param, ReturnT.class);

            if (returnT != null && returnT.getContent() != null) {
                jobInfo.setJobGroup(returnT.getContent());
                log.info(
                        "【find xxl GroupId by appname: {} , get groupId : {}】",
                        appname,
                        returnT.getContent());
                @SuppressWarnings("unchecked")
                ReturnT<String> addReturn =
                        restTemplate.postForObject(
                                adminAddresses + ADD_URL, jobInfo, ReturnT.class);
                if (addReturn != null && 200 == addReturn.getCode()) {
                    log.info("【add xxlJobInfo success jobInfo:{}】", jobInfo);
                }
            }

        } catch (Exception e) {
            log.error("【add xxlJobInfo fail error : {}】", e.getMessage());
        }
    }

    public void remove(String handler, String cron) {
        XxlJobInfo xxlJobInfo = new XxlJobInfo();
        xxlJobInfo.setExecutorHandler(handler).setScheduleConf(cron);
        Map<String, String> param = new HashMap<>(1);
        param.put(APP_NAME, appname);
        ReturnT<Integer> returnT =
                restTemplate.postForObject(adminAddresses + GET_GROUP_ID, param, ReturnT.class);

        if (returnT != null && returnT.getContent() != null) {
            xxlJobInfo.setJobGroup(returnT.getContent());
        }
        @SuppressWarnings("unchecked")
        ReturnT<Integer> removeReturn =
                restTemplate.postForObject(adminAddresses + REMOVE_URL, xxlJobInfo, ReturnT.class);
        if (removeReturn != null && 200 == removeReturn.getCode()) {
            log.info("【remove xxlJobInfo success jobInfo:{}】", xxlJobInfo);
        }
    }
}
